/*
 * Tranquil Java Integrated Development Environment
 *
 * The GNU General Public License Version 3
 *
 * Copyright (C) 2021 Autumn Lamonte
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Autumn Lamonte [AutumnWalksTheLake@gmail.com] ⚧ Trans Liberation Now
 * @version 1
 */
package tjide.project;

import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The style of license for a project.
 */
public class License {

    // ------------------------------------------------------------------------
    // Constants --------------------------------------------------------------
    // ------------------------------------------------------------------------


    // ------------------------------------------------------------------------
    // Variables --------------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * The short name, e.g. "MIT", "GPLv2+", "GPLv3", "Proprietary".
     */
    private String name;

    /**
     * Some short descriptive text for the license, what would be emitted by
     * a --version command line option.
     */
    private String description;

    /**
     * The full text of the license terms.
     */
    private String fullText;

    /**
     * The header for this license that would appear in every source file.
     */
    private String sourceHeader;

    /**
     * Loaded licenses.
     */
    private static Map<String, License> licenses = new HashMap<String, License>();

    // ------------------------------------------------------------------------
    // Constructors -----------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Private constructor used by the static constructor.
     *
     * @param name the short name, e.g. "MIT", "Eclipse", "GPLv3",
     * "Proprietary, etc.
     * @param description short descriptive text for the license, what would
     * be emitted by a --version command line option.
     * @param fullText the full text of the license terms.
     * @param sourceHeader the header for this license that would appear in
     * every source file.
     */
    private License(final String name, final String description,
        final String fullText, final String sourceHeader) {

        this.name               = name;
        this.description        = description;
        this.fullText           = fullText;
        this.sourceHeader       = sourceHeader;

        synchronized (licenses) {
            licenses.put(name, this);
        }
    }

    /**
     * Static constructor.  Attempt to load all of the license texts in the
     * resources directory into licenses.
     */
    static {
        try {
            ClassLoader loader = ClassLoader.getSystemClassLoader();
            String [] available = {
                "Apache-1.1", "Apache-2.0", "BSD", "GPL-2", "GPL-3",
                "LGPL-2.1", "LGPL-3", "MIT", "Proprietary", "PublicDomain"
            };
            for (int i = 0; i < available.length; i++) {
                StringWriter writer = null;
                InputStreamReader input = null;

                // fullText
                input = new InputStreamReader(loader.
                    getResourceAsStream("licenses/" +
                        available[i] + "/fullText"), "UTF-8");
                writer = new StringWriter();
                for (int ch = input.read(); ch != -1; ch = input.read()) {
                    writer.write(ch);
                }
                String fullText = writer.toString();

                // description
                input = new InputStreamReader(loader.
                    getResourceAsStream("licenses/" +
                        available[i] + "/description"), "UTF-8");
                writer = new StringWriter();
                for (int ch = input.read(); ch != -1; ch = input.read()) {
                    writer.write(ch);
                }
                String description = writer.toString();

                // sourceHeader
                input = new InputStreamReader(loader.
                    getResourceAsStream("licenses/" +
                        available[i] + "/sourceHeader"), "UTF-8");
                writer = new StringWriter();
                for (int ch = input.read(); ch != -1; ch = input.read()) {
                    writer.write(ch);
                }
                String sourceHeader = writer.toString();

                licenses.put(available[i], new License(available[i],
                        description, fullText, sourceHeader));
            }

            /* DEBUG
            for (License l: licenses.values()) {
                System.err.println("===================");
                System.err.println(l.name);
                System.err.println("-----------------");
                System.err.println(l.fullText);
                System.err.println("-----------------");
                System.err.println(l.description);
                System.err.println("-----------------");
                System.err.println(l.sourceHeader);
                System.err.println("===================");
            }
            */

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // ------------------------------------------------------------------------
    // License ----------------------------------------------------------------
    // ------------------------------------------------------------------------

    /**
     * Get the list of license short names.
     *
     * @return a list containing the short names of all loaded licenses, e.g.
     * [ "MIT", "Eclipse", "GPLv3", "Proprietary", ... ]
     */
    public static List<String> getLicenseNames() {
        synchronized (licenses) {
            List<String> names = new ArrayList<String>(licenses.keySet());
            Collections.sort(names);
            return names;
        }
    }

    /**
     * Get a common license using its short name.
     *
     * @param name the short name, e.g. "MIT", "Eclipse", "GPLv3",
     * "Proprietary", etc.
     * @return the license, or null if not found
     */
    public static License getLicense(final String name) {
        synchronized (licenses) {
            return licenses.get(name);
        }
    }

    /**
     * Get the short name.
     *
     * @return the name e.g. "MIT", "GPLv2+", "GPLv3", "Proprietary".
     */
    public String getName() {
        return name;
    }

    /**
     * Get the short descriptive text for the license, what would be emitted
     * by a --version command line option.
     *
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * Get the full text of the license terms.
     *
     * @return the full license text in all its glory
     */
    public String getFullText() {
        return fullText;
    }

    /**
     * Get the header for this license that would appear in every source
     * file.
     *
     * @return the header text
     */
    public String getSourceHeader() {
        return sourceHeader;
    }

}
